perm filename IMPUDP[IP,SYS] blob
sn#741324 filedate 1984-02-05 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00006 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 .FATAL This code is far from ready. -- JJW
C00003 00003 Initialize UDP service UDPINI
C00004 00004 MTAPE to write a UDP packet UDPWRT UDPWR1 UDPWR2 UDPWR3
C00008 00005 MTAPE to read a UDP packet. UDPREA STTERR UDPRE1 UDPRED UDPFLS UDPREW
C00013 00006 MTAPE to get a free UDP local port number, stored in word 1 of MTAPE block GENUDP UDPPRT UDPPR1 UDPPR2
C00017 ENDMK
C⊗;
.FATAL This code is far from ready. -- JJW
Comments:
The following code contains TCP assumptions and must be fixed for UDP:
In NETSUB: BIBMAK sets up retransmission.
;IMPSER code for UDP protocol
;Definitions
UDRPRT←←400 ;Reserve ports 0-377
;Storage
UDFPRT: BLOCK 1 ;Last UDP free port assigned
;Initialize UDP service ;⊗ UDPINI
UDPINI: MOVEI TAC,UDRPRT
MOVEM TAC,UDFPRT
POPJ P,
;MTAPE to write a UDP packet ;⊗ UDPWRT UDPWR1 UDPWR2 UDPWR3
; MTAPE <chan>,ADR
;ADR: 30
; <status bits returned>
; <local port>
; <user addr of packet data>
; <packet length>
; <foreign port>
; <foreign host>
UDPWRT: XCTR XR,[SKIPLE DAT,BSLOC(UUO)] ;Get packet length
;JJW - get right max packet size
CAILE DAT,=512 ;Range check
JRST ADRERR ;Address check if bad length
MOVEI TAC,3(DAT) ;Round up to words
LSH TAC,-2
XCTR XR,[MOVE TAC1,WFLOC(UUO)] ;Get user buffer address
ADDI TAC1,-1(TAC) ;Last word in buffer
XCTR XR,[MOVE TAC,(TAC1)] ;Address check
XCTR XR,[MOVE TAC1,WFLOC(UUO)] ;Get buffer address again
HRLI TAC1,441000 ;Make 8-bit byte ptr
XCTR XR,[SKIPGE TAC,LSLOC(UUO)] ;Get local port from user
PUSHJ P,UDPPRT ;He wants us to make one
ANDI TAC,177777 ;Make it legal
MOVEM TAC,LCLPRT(DDB)
XCTR XW,[MOVEM TAC,LSLOC(UUO)] ;Tell him the port
XCTR XR,[MOVE TAC,FSLOC(UUO)] ;Get foreign port
ANDI TAC,177777
MOVEM TAC,RMTPRT(DDB)
XCTR XR,[MOVE TAC,HLOC(UUO)] ;Get foreign host
MOVEM TAC,RMTADR(DDB)
PUSHJ P,SAVALL ;Enter TOPS-10 mode
SETAC(T1,TAC) ;Get foreign host address
PUSHJ P,TARGET↑ ;Find a place to send this packet
JRST CGTERR ;Can't get there
MOVEM T1,NETADR(F)
MOVEM W,NETWRK(F)
;Now copy the data into IMP buffers (byte-by-byte, as we checksum)
;and send it out.
SETAC(P1,TAC1) ;Starting address
SETAC(P2,DAT) ;Length in bytes
;P3 accumulates the checksum
MOVEI P4,OUBYTE↑ ;Coroutine linkage
UDPWR1: XCTR XLB,[ILDB T1,P1] ;Get a byte
JSP P4,(P4) ;Store it
JRST UDPWR3 ;Error (no more buffers)
SOJG P2,UDPWR1 ;Loop for more
PUSHJ P,OUTBFX↑ ;Link last buffer to stream
OFFSCN ;Blecchhh
PUSHJ P,OUTPRE↑ ;Ensure enough room (UDP takes less than TCP,
;so OUTPRE is usable).
JRST UDPWR2 ;Not enough, lose
PUSHJ P,UDPMAK↑ ;Send it away!
JRST SCNONJ ;That's all, folks
UDPWR2: ONSCN
UDPWR3: MOVE T1,OBFFST(F) ;Point to beginning of stream
PUSHJ P,RELBUF↑ ;Flush it all
SETZM OBFFST(F)
POPJ P, ;Just return
;MTAPE to read a UDP packet. ;⊗ UDPREA STTERR UDPRE1 UDPRED UDPFLS UDPREW
; MTAPE <chan>,ADR
;ADR: 31 ;Read or request a UDP packet
; <status bits returned>
; <local port>
; <user addr of packet data>
; <packet length returned>
; <foreign port>
; <foreign host>
UDPREA: MOVEI TAC,.IPUDP ;IP protocol code for UDP
CAME TAC,PROTCL(DDB) ;Check protocol in DDB
SKIPN STATE(DDB) ;Not UDP, but OK if closed
JRST UDPRE1 ;Jump if DDB state OK
STTERR: MOVEI TAC,E.STT↑ ;Code for state error (defined in TCPSER.MAC)
XCTR XW,[MOVEM TAC,STLOC(UUO)]
POPJ P,
UDPRE1: MOVEM TAC,PROTCL(DDB) ;Now we're in UDP for sure
XCTR XW,[SETZM STLOC(UUO)] ;No errors yet
SKIPE IBFTHS(DDB) ;Flush any currently waiting packet
PUSHJ P,UDPFLS
SETOM IBFTHS(DDB) ;Lock out packet input
XCTR XR,[MOVE TAC,LSLOC(UUO)] ;Copy local port to DDB
MOVEM TAC,LCLPRT(DDB)
XCTR XR,[MOVE TAC,FSLOC(UUO)] ;Copy foreign port to DDB
MOVEM TAC,RMTPRT(DDB)
XCTR XR,[MOVE TAC,HLOC(UUO)] ;Copy foreign host to DDB
MOVEM TAC,RMTADR(DDB)
MOVSI IOS,IDATWT ;Set wait bit
IORB IOS,DEVIOS(DDB)
SETZM IBFTHS(DDB) ;Allow new packet to arrive
;Enter here for MTAPE to wait for previously requested packet.
UDPRED: PUSHJ P,SAVALL ;Enter TOPS-10 mode
XCTR XR,[SKIPE P4,WFLOC(UUO)] ;See if user buffer given
PUSHJ P,UDPREW ;Wait for packet or error
POPJ P, ;No buffer or error (probably timeout)
SKIPN P1,IBFTHS(F) ;Make sure there really is a packet
POPJ P, ;No, there isn't
MOVE P2,MSGLEN(F) ;Get packet length
XCTR XW,[MOVEM P2,BSLOC(F)] ;Return in MTAPE block
ADDI P2,3 ;Round up to multiple of 4
LSH P2,-2 ;Convert bytes to words
UDPRE2: MOVSI T1,NBHLEN(P1) ;Source for BLT
HRRI T1,(P4) ;Destination
MOVEI T2,IMPBFS-NBHLEN ;Number of data words in an IMP buffer
CAILE T2,(P2) ;Number of words to BLT
MOVEI T2,(P2)
SUBI P2,(T2) ;Decrement count
ADDI P4,(T2) ;First word after BLT
XCTR XBLTW,[BLT T1,(P4)] ;Transfer one IMP buffer
HRRZ P1,(P1) ;Advance to next buffer
JUMPE P2,UDPRE3 ;Unless done
JUMPN P1,UDPRE2 ;Make sure there is a buffer
PUSHJ P,BUGTRP ;Oops!
JRST UDPRE4 ;Just exit quietly if continued
UDPRE3: JUMPE P1,.+2 ;If done, there should be no buffers
PUSHJ P,BUGTRP ;Wrong again
UDPRE4: MOVE T1,IBFTHS(F) ;Get pointer to buffer stream
PUSHJ P,RELBUF↑ ;Release them all
SETZM IBFTHS(F)
POPJ P,
;Here to flush packet pointed to by DDB.
UDPFLS: PUSHJ P,SAVT↑ ;Get T-registers (restored on return from RELBUF)
HRRZ T1,IBFTHS(DDB) ;Point to beginning of buffer stream
JRST RELBUF↑ ;(in NETSUB.MAC)
;Here to wait for a packet (ACs in TOPS-10 mode).
UDPREW: LDB T1,INPTP ;Get input wait time
LSH T1,2 ;Convert to seconds
PUSHJ P,IMPWAT ;Wait for data
TRNN S,TMO ;Check for timeout
JRST CPOPJ1 ;No, should be OK
;JJW - do we need to do this?
MOVEI S,IODERR ;Set error bit with timeout
IORB S,DEVIOS(F)
POPJ P,
;MTAPE to get a free UDP local port number, stored in word 1 of MTAPE block ;⊗ GENUDP UDPPRT UDPPR1 UDPPR2
GENUDP: PUSHJ P,UDPPRT ;Get a free UDP port
XCTR XW,[MOVEM TAC,1(UUO)]
POPJ P,
UDPPRT: AOS TAC,UDFPRT ;Get next port number
TRNN TAC,200000 ;Skip if more than 16 bits
JRST UDPPR1
MOVEI TAC,UDRPRT ;Reserve well-known ports
MOVEM TAC,UDFPRT
UDPPR1: MOVEI TAC1,IMPDDB ;Start search through DDBs
UDPPR2: HLRZ TAC1,DEVSER(TAC1) ;Get next DDB
CAIN TAC1,IMP.NX ;End of IMP DDBs?
POPJ P, ;Yes, done
CAMN TAC,LCLPRT(TAC1) ;Is port the same?
JRST UDPPRT ;Yes, try all over again
JRST UDPPR2 ;Keep checking